home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / shutdown.lzh / shutdown_5.1 / src / sdwarn.c < prev    next >
C/C++ Source or Header  |  1996-12-02  |  6KB  |  288 lines

  1. /*
  2.    sdwarn.c --- example shutdown client.
  3.  
  4.    (c) Copyright 1995 SHW Wabnitz
  5.    Written by Bernhard Fastenrath (fasten@shw.com)
  6.  
  7.    This file may be distributed under the terms
  8.    of the GNU General Public License.
  9. */
  10.  
  11. #if defined (__SASC)
  12. #include <dos.h>
  13. #endif
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <exec/types.h>
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20.  
  21. #include "queue/queue.h"
  22. #include "queue/shutdown.h"
  23.  
  24. #if defined (__GNUC__)
  25. #include "queue/queue_inline.h"
  26. #elif defined (__SASC_60)
  27. #include "queue/queue_pragmas.h"
  28. #endif
  29.  
  30. void CloseTimerDevice (void);
  31. int CheckCLISession (void);
  32.  
  33. struct Library *QueueBase = NULL;
  34. struct timerequest *TimerReq = NULL;
  35. struct MsgPort *TimerPort = NULL;
  36. ULONG TimerMask = 0;
  37. ULONG QueueMask = 0;
  38. ULONG CliNumber = 0;
  39. BPTR CliStdout = NULL;
  40. struct Process *MyProc;
  41. APTR WindowPtr;
  42.  
  43. char *optarg = NULL;
  44.  
  45. int
  46. getopt (int argc, char *const *argv, const char *opts)
  47. {
  48.   static int pos = 0;
  49.   char *c;
  50.  
  51.   while (++pos < argc && argv[pos][0] != '-');
  52.   if (pos >= argc)
  53.     return -1;
  54.   if ((c = strchr (opts, (int) argv[pos][1])) == 0)
  55.     return (int) '?';
  56.   if (*(c+1) != ':')
  57.     return (int) *c;
  58.   if (strlen (argv[pos]) > 2)
  59.     optarg = argv[pos] + 2;
  60.   else if (pos+1 < argc)
  61.     optarg = argv[pos+1];
  62.   else
  63.     return (int) '?';
  64.   return (int) *c;
  65. }
  66.  
  67. int
  68. CheckCLISession (void)
  69. {
  70.   struct Process *pr;
  71.   int code = 0;
  72.  
  73.   if (!CliNumber)
  74.     return 1;
  75.  
  76.   Forbid ();
  77.   if (pr = FindCliProc (CliNumber))
  78.   {
  79.     /* We might have found a new CLI
  80.        with the same number.
  81.     */
  82.     if (pr -> pr_COS == CliStdout)
  83.       code = 1;
  84.   }
  85.   Permit ();
  86.   return code;
  87. }
  88.  
  89. void
  90. CloseTimerDevice (void)
  91. {
  92.   if (!TimerPort)
  93.     return;
  94.  
  95.   AbortIO ((struct IORequest *) TimerReq);
  96.   WaitIO ((struct IORequest *) TimerReq);
  97.   CloseDevice ((struct IORequest *) TimerReq);
  98.   DeleteIORequest (TimerReq);
  99.   DeleteMsgPort (TimerPort);
  100.   TimerPort = NULL;
  101. }
  102.  
  103. void
  104. StartTimer (void)
  105. {
  106.   if (TimerPort)
  107.   {
  108.     TimerReq -> tr_node.io_Command = TR_ADDREQUEST;
  109.     TimerReq -> tr_time.tv_secs  = 3;
  110.     TimerReq -> tr_time.tv_micro = 0;
  111.     SendIO ((struct IORequest *) TimerReq);
  112.   }
  113. }
  114.  
  115. ULONG
  116. OpenTimerDevice (void)
  117. {
  118.   if (!(TimerPort = CreateMsgPort ()))
  119.     return 0;
  120.  
  121.   if (!(TimerReq = (struct timerequest *)
  122.     CreateIORequest (TimerPort, sizeof (struct timerequest))))
  123.   {
  124.     DeleteMsgPort (TimerPort);
  125.     return 0;
  126.   }
  127.   if (OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerReq, 0))
  128.   {
  129.     DeleteIORequest (TimerReq);
  130.     DeleteMsgPort (TimerPort);
  131.     return 0;
  132.   }
  133.   StartTimer ();
  134.   return TimerMask = 1 << TimerPort -> mp_SigBit;
  135. }
  136.  
  137. void
  138. GoingDownMessage (int seconds)
  139. {
  140.   if (seconds / 3600)
  141.     printf ("The system is going down in %d:%.2d hours.\n",
  142.             seconds / 3600, (seconds % 3600) / 60);
  143.   else if (seconds / 60)
  144.     printf ("The system is going down in %d:%.2d minutes.\n",
  145.             seconds / 60, seconds % 60);
  146.   else
  147.     printf ("The system is going down in %d seconds.\n", seconds);
  148. }
  149.  
  150. int
  151. main (int argc, char *argv[])
  152. {
  153.   QMessage *qmsg, *lqmsg;
  154.   ShutdownMessage *sm;
  155.   UpsInfo *ups;
  156.   char *UpsEvents[] = UPS_EV_NAMES;
  157.   int verbose = 0;
  158.   ULONG sigbit, sigmask, rmask;
  159.   QHandle qh;
  160.   int opt;
  161.  
  162.   MyProc = (struct Process *) FindTask (0);
  163.   WindowPtr = MyProc -> pr_WindowPtr;
  164.   MyProc -> pr_WindowPtr = (void *) -1;
  165.  
  166.   while ((opt = getopt (argc, argv, "c:v")) != -1)
  167.     switch (opt)
  168.     {
  169.       case 'v': verbose = 1; break;
  170.       case 'c':
  171.         if (CliNumber = atoi (optarg))
  172.         {
  173.           struct Process *pr;
  174.  
  175.           Forbid ();
  176.           if (pr = FindCliProc (CliNumber))
  177.         CliStdout = pr -> pr_COS;
  178.           Permit ();
  179.           if (!CliStdout)
  180.           {
  181.         printf ("Invalid CLI.\n", CliNumber);
  182.         exit ( EXIT_FAILURE );
  183.           }
  184.         }
  185.     break;
  186.       default:
  187.         printf ("Usage: %s [-v] [-c <cli>].\n", argv[0]);
  188.     exit (EXIT_FAILURE);
  189.     }
  190.  
  191.   if (!(QueueBase = OpenLibrary ("queue.library", 0)))
  192.   {
  193.     printf ("Failed to open queue.library.\n");
  194.     return EXIT_FAILURE;
  195.   }
  196.   if (CliNumber)
  197.   {
  198.     if (!OpenTimerDevice ())
  199.     {
  200.       printf ("Failed to open timer.device.\n");
  201.       CloseLibrary (QueueBase);
  202.       return EXIT_FAILURE;
  203.     }
  204.   }
  205.   if ((sigbit = AllocSignal (-1)) != -1)
  206.   {
  207.     QueueMask = 1 << sigbit;
  208.     sigmask = SIGBREAKF_CTRL_C | TimerMask | QueueMask;
  209.  
  210.     if (qh = QOpen ("shutdown", QMODE_LISTEN, sigbit))
  211.     {
  212.       while (1)
  213.       {
  214.     rmask = Wait (sigmask);
  215.     if (rmask & TimerMask)
  216.       StartTimer ();
  217.  
  218.         if (rmask & QueueMask)
  219.         {
  220.       lqmsg = NULL;
  221.       while (qmsg = QGetMsg (qh))
  222.       {
  223.         sm = (ShutdownMessage *) qmsg -> qm_Data;
  224.             lqmsg = qmsg;
  225.  
  226.         switch (sm -> sm_Status)
  227.         {
  228.           case SHUTDOWN_WARN:
  229.           case SHUTDOWN_NOW:
  230.             GoingDownMessage (sm -> sm_TimeLeft);
  231.             break;
  232.           case SHUTDOWN_INFO:
  233.             if (verbose)
  234.                 {
  235.               if (sm -> sm_Info == SDMI_UPS_MONITOR)
  236.                   {
  237.                 printf ("Shutdown info received:\n");
  238.                     ups = sm -> sm_Extra;
  239.                     if (ups -> ui_Event > UPS_EV_MAX)
  240.                       printf ("Event = %d (unknown)\n", ups -> ui_Event);
  241.                     else
  242.                       printf ("Event = %s.\n", UpsEvents[ups -> ui_Event]);
  243.                 printf ("Charge = %d.\n", ups -> ui_Charge);
  244.                 printf ("Remaining time = %d.\n", ups -> ui_Time);            
  245.                   }
  246.               else
  247.                 printf ("Shutdown info received.\n");
  248.                 }
  249.             break;
  250.           case SHUTDOWN_ABORT:
  251.             printf ("Shutdown has been aborted.\n");
  252.             break;
  253.           case SHUTDOWN_UMOUNT:
  254.             printf ("The system is going down, unmounting filesystems.\n");
  255.             break;
  256.           case SHUTDOWN_HALT:
  257.             printf ("The system is halted.\n");
  258.             break;
  259.           default:
  260.             printf ("Unknown message.\n");
  261.             break;
  262.         }
  263.           }
  264.       if (lqmsg)
  265.         QReplyMsg (qh);
  266.     }
  267.         if (rmask & SIGBREAKF_CTRL_C || !CheckCLISession ())
  268.         {
  269.       if (rmask & SIGBREAKF_CTRL_C)
  270.         printf ("CTRL-C\n");
  271.       else
  272.         printf ("\n%s: End of session.\n", argv[0]);
  273.       QClose (qh);
  274.       break;
  275.         }
  276.       }
  277.     }
  278.     else
  279.       printf ("Can't open shutdown queue.\n");
  280.   }
  281.   else
  282.     printf ("Can't allocate signal.\n");
  283.   CloseTimerDevice ();
  284.   CloseLibrary (QueueBase);
  285.   MyProc -> pr_WindowPtr = WindowPtr;
  286.   exit ( EXIT_SUCCESS );
  287. }
  288.